home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / BASE64.C < prev    next >
C/C++ Source or Header  |  1997-01-18  |  4KB  |  177 lines

  1. #include "config.h"
  2.  
  3. #include <sys/types.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6.  
  7.  
  8. #if !defined(_lint)
  9. static char rcsid[] OPTIONAL = "$Id: base64.c,v 1.8 1997/01/18 16:13:20 root Exp root $";
  10. #endif
  11.  
  12. #if defined(HTTP) || defined(BROWSER) || defined(TEST)
  13.  
  14. char *strToBase64 (char *str);
  15. char *base64ToStr (char *b64);
  16. static int findBase64 (char c);
  17. extern void *mallocw (unsigned nb);
  18.  
  19. #define NULLCHAR ((char *)0)
  20.  
  21. static char lkBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  22.  
  23. static int
  24. findBase64 (c)
  25. char c;    
  26. {
  27. int k;
  28.     for (k = 0; k < 64; k++)
  29.         if (lkBase64[k] == c)
  30.             return k;
  31.     return -1;
  32. }
  33.  
  34.  
  35. /* returns a malloc'ed string which is the original string converted to
  36.    base64, or NULLCHAR if cannot malloc, per RFC 1521 */
  37. char *
  38. strToBase64 (char *thestr)
  39. {
  40. char *b64, *out;
  41. unsigned char *str = (unsigned char *)thestr;
  42. int multiple, remainder, len;
  43. int val;
  44.  
  45.     len = (int) strlen((char *)str);
  46.     multiple = len / 3;
  47.     remainder = len % 3;
  48.  
  49.     out = b64 = mallocw ((unsigned int)(((multiple + 1) * 4) + 1));
  50.     if (out == NULLCHAR)
  51.         return out;
  52.  
  53.     while (multiple--)    {
  54.         out[0] = lkBase64[(str[0] >> 2) & 0x3f];
  55.         val = (str[1] >> 4) & 0x0f;
  56.         out[1] = lkBase64[val | ((str[0] << 4) & 0x30)];
  57.         val = (str[1] << 2) & 0x3c;
  58.         out[2] = lkBase64[val | ((str[2] >> 6) & 3)];
  59.         out[3] = lkBase64[str[2] & 0x3f];
  60.  
  61.         out += 4;
  62.         str += 3;
  63.     }
  64.     out[0] = 0;
  65.     if (remainder != 0)    {
  66.         out[0] = lkBase64[(str[0] >> 2) & 0x3f];
  67.         out[1] = out[2] = out[3] = '=';
  68.         out[4] = 0;
  69.         if (remainder == 2) {
  70.             val = (str[1] >> 4) & 0x0f;
  71.             out[1] = lkBase64[val | ((str[0] << 4) & 0x30)];
  72.             out[2] = lkBase64[(str[1] << 2) & 0x3c];
  73.         } else {
  74.             out[1] = lkBase64[(str[0] << 4) & 0x30];
  75.         }
  76.     }
  77.     return (b64);
  78. }
  79.  
  80.  
  81. /* returns a malloc'ed string which is the original string converted from
  82.    base64, per RFC 1521 - Returns a NULLCHAR if invalid characters
  83.    found or memory cannot be allocated, otherwise the memory must
  84.    STILL be freed. */
  85. char *
  86. base64ToStr (char *b64)
  87. {
  88. char *str, *out;
  89. int multiple, remainder = 0, pad = 0, len;
  90. int val, temp;
  91.  
  92.     len = (int) strlen ((char *)b64);
  93.     multiple = len / 4;
  94.     if (b64[len - 1] == '=')
  95.         pad++;
  96.     if (b64[len - 2] == '=')
  97.         pad++;
  98.     switch (pad)    {
  99.         case 2:        remainder = 1;
  100.                 break;
  101.         case 1:        remainder = 2;
  102.                 break;
  103.         case 0:
  104.         default:    break;
  105.                 
  106.     }
  107.     if (pad)
  108.         multiple--;
  109.     out = str = mallocw ((unsigned int)((multiple * 3) + 1));
  110.     if (out == NULLCHAR)
  111.         return out;
  112.  
  113.     while (multiple--)    {
  114.         if ((temp = findBase64 (b64[0])) == -1)
  115.             goto error;
  116.         val = (temp << 2);            /*lint !e701 */
  117.         if ((temp = findBase64 (b64[1])) == -1)
  118.             goto error;
  119.         out[0] = val | ((temp >> 4) & 3);    /*lint !e702 !e734 */
  120.         val = (temp & 0x0f) << 4;
  121.         if ((temp = findBase64 (b64[2])) == -1)
  122.             goto error;
  123.         out[1] = val | ((temp >> 2) & 0x0f);    /*lint !e702 !e734 */
  124.         out[2] = (temp << 6);            /*lint !e701 !e734 */
  125.         if ((temp = findBase64 (b64[3])) == -1)
  126.             goto error;
  127.         out[2] |= temp;                /*lint !e734 */
  128.             
  129.         out += 3;
  130.         b64 += 4;
  131.     }
  132.     out[0] = 0;
  133.     if (remainder != 0)    {
  134.         if ((temp = findBase64 (b64[0])) == -1)
  135.             goto error;
  136.         val = (temp << 2);            /*lint !e701 */
  137.         if ((temp = findBase64 (b64[1])) == -1)
  138.             goto error;
  139.         out[0] = val | ((temp >> 4) & 3);    /*lint !e702 !e734 */
  140.         out[1] = 0;
  141.         if (remainder == 2)    {
  142.             if ((temp = findBase64 (b64[1])) == -1)
  143.                 goto error;
  144.             val = (temp & 0x0f) << 4;
  145.             if ((temp = findBase64 (b64[2])) == -1)
  146.                 goto error;
  147.             out[1] = val | ((temp >> 2) & 0x0f);    /*lint !e702 !e734 */
  148.             out[2] = 0;
  149.         }
  150.     }
  151.     return (str);
  152.  
  153. error:
  154.     str[0] = 0;        /*lint !e613 */
  155.     return (str);
  156. }
  157.  
  158. #ifdef TEST
  159. void
  160. main (argc, argv)
  161. int argc;
  162. char *argv[];
  163. {
  164.     if (argc != 3)
  165.         exit (0);
  166.  
  167.     if (argv[1][0] == 't')
  168.         printf ("Encoding '%s': '%s'\n", argv[2], strToBase64 ((unsigned char *)argv[2]));
  169.     else
  170.         printf ("Decoding '%s': '%s'\n", argv[2], base64ToStr ((unsigned char *)argv[2]));
  171. }
  172.  
  173.  
  174. #endif    /* TEST */
  175.  
  176. #endif    /* HTTP */
  177.